/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

#ifndef OSGI_PROPERTIES_HH
#define OSGI_PROPERTIES_HH

#include "OSGi.hh"

/*! @file OSGi/Properties.hh
    @brief Class OSGi::Properties header.
    @author @ref Guillaume_Terrissol
    @date 11th December 2009 - 26th May 2013
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <map>
#include <string>

#include "Exception.hh"

namespace OSGi
{
//------------------------------------------------------------------------------
//                                  Properties
//------------------------------------------------------------------------------

    /*! @brief Property list.
        @version 0.9

        Instances of this class are used to hold properties (pairs of key-value).
     */
    class OSGI_EXPORT Properties
    {
    public:
        //! @name Constructor & destructor
        //@{
                            Properties();                                       //!< Constructor.
                            ~Properties();                                      //!< Destructor.
        //@}
        //! @name Property definition
        //@{
        void        set(std::string pKey, std::string pValue);                  //!< ... as string.
        void        set(std::string pKey, bool pValue);                         //!< ... as boolean.
        void        set(std::string pKey, int pValue);                          //!< ... as integer.
        void        set(std::string pKey, double pValue);                       //!< ... as float.
        void        set(std::string pKey, const char* pValue);                  //!< ... as C string.
        //@}
        //! @name Property retrieving
        //@{
        bool        has(const std::string& pKey) const;                         //!< Key presence check.
        std::string get(const std::string& pKey) const;                         //!< ... as string.
        bool        getBool(const std::string& pKey) const;                     //!< ... as boolean.
        int         getInteger(const std::string& pKey) const;                  //!< ... as integer.
        double      getFloat(const std::string& pKey) const;                    //!< ... as float.
        //@}
        //! @name Property retrieving (with default value)
        //@{
        std::string get(const std::string& pKey, std::string pDefault) const;   //!< ... as string.  
        bool        getBool(const std::string& pKey, bool pDefault) const;      //!< ... as boolean.
        int         getInteger(const std::string& pKey, int pDefault) const;    //!< ... as integer.
        double      getFloat(const std::string& pKey, double pDefault) const;   //!< ... as float.


    private:

        template<typename TT>
        TT          retrieve(const std::string& pKey, TT pDefault) const;       //!< ... generic.
        //@}
        std::map<std::string, std::string>  mValues;                            //!< Properties.
    };

    
//------------------------------------------------------------------------------
//                                  Missing Key
//------------------------------------------------------------------------------

    /*! @brief Exception on missing key.
        @version 0.6

        This exception class is used to signal a missing key in a Properties
        instance accessed with any "non-defaulted" Properties::get*() method.
     */
    class OSGI_EXPORT KeyNotFound : public Exception
    {
    public:
        //! @name Interface
        //@{
explicit                    KeyNotFound(std::string pKey);  //!< Constructor.
virtual                     ~KeyNotFound() noexcept;        //!< Destructor.
virtual const std::string&  key() const noexcept;           //!< Information.
        //@}

    private:

        std::string mKey;                                   //!< Missing key name.
    };
}

#endif  // OSGI_PROPERTIES_HH
